#include "dmLite.h"
#include "gizwits_protocol.h"

extern gizwitsProtocol_t gizwitsProtocol;
extern void subDevIssuedProcessCB(PRO_TYPE proType,uint8_t *subDevID,uint8_t * data, uint32_t len);
extern int8_t gizProtocolWaitAck(uint8_t *gizdata, uint32_t len);

static void ICACHE_FLASH_ATTR gGatewayLiteUploadDataCB(int32_t result, void *arg,uint8_t *pszDID)
{
    GIZWITS_LOG("[uploadDataCBFunc]: result %d \n", result);
}

int8_t ICACHE_FLASH_ATTR gGatewayLiteInit(void)
{
    return 0;
}

int8_t ICACHE_FLASH_ATTR gGatewayLiteExit(void)
{
    return 0;
}

int8_t ICACHE_FLASH_ATTR gGatewayLiteSubDevIssuedProcess(uint8_t *data, uint32_t len)
{
    uint8_t  subDevIDLen = 0;
    uint8_t  subDevID[256] = {0};
    uint32_t offset = 0;
    PRO_TYPE proType;

    if(NULL == data)
    {
        GIZWITS_LOG("[gGatewayLiteSubDevIssuedProcess]: Input data is NULL \n");
        return -1;
    }

    subDevIDLen = data[0];
    offset += 1;

    memcpy(subDevID, &data[offset], subDevIDLen);
    offset += subDevIDLen;
    subDevID[offset] = '\0';

    switch(data[offset]) //action
    {
        case 0x01:
        case 0x02:
            proType = STANDARD_TYPE;
            break;
        case 0x11:
        case 0x12:
            proType = VARLEN_TYPE;
            break;
        case 0x05:
            proType = TRANSPARENT_TYPE;
            break;
        default:
            break;
    }
    offset += 1;

    subDevIssuedProcessCB(proType, subDevID, (uint8_t *)data+offset, len-offset);

    return 0;
}

int32_t ICACHE_FLASH_ATTR gGatewayLiteUpLoadData(PRO_TYPE proType, uint8_t *subDevID, uint8_t *data, uint32_t len)
{
		uint8_t *tmpPtr = NULL;
    uint8_t *uploadDataPtr = NULL;
    int32_t ret = 0;
    uint32_t uploadDataLen = 0;
    uint32_t offset = 0;

    if(NULL == data)
    {
        GIZWITS_LOG("[gGatewayLittleUpLoadData]:Input data is NULL \n");
        return -1;
    }

    uploadDataLen = len + gizStrlen(subDevID) + 12; //gateway action + subdevid len + subdevid + subdev action + data len
    tmpPtr = (uint8_t *)gizMalloc(uploadDataLen);
    if(NULL == tmpPtr)
    {
        GIZWITS_LOG("[gGatewayLittleUpLoadData]:Failed to malloc buffer, size %d \n", uploadDataLen);
        return -128;
    }

		uploadDataLen -= 4;
		
		tmpPtr[0] = 0xFF;
		tmpPtr[1] = 0xFF;
		tmpPtr[2] = (uint8_t)(uploadDataLen>>8);//len
		tmpPtr[3] = (uint8_t)(uploadDataLen);
		tmpPtr[4] = CMD_REPORT_P0;//0x1b cmd
		tmpPtr[5] = gizwitsProtocol.sn++;//sn
		tmpPtr[6] = 0x00;//flag
		tmpPtr[7] = 0x00;//flag
		
		uploadDataLen += 4;
		
		uploadDataPtr	= tmpPtr+8;
		
    //gateway action 
    uploadDataPtr[offset] = ACTION_GATEWAY_SINGLE_UPLOAD;
    offset += 1;

    //subdevid len
    uploadDataPtr[offset] = gizStrlen(subDevID);
    offset += 1;

    //subdev id
    gizMemcpy((uint8_t *)&uploadDataPtr[offset], subDevID, gizStrlen(subDevID));
    offset += gizStrlen(subDevID);

    switch(proType)
    {
        case STANDARD_TYPE:
            uploadDataPtr[offset] = 0x04;
            break;
        case VARLEN_TYPE:
            uploadDataPtr[offset] = 0x14;
            break;
        case TRANSPARENT_TYPE:
            uploadDataPtr[offset] = 0x06;
            break;
        default:
            break;
    }
    offset += 1;

    gizMemcpy((uint8_t *)((uint8_t *)&uploadDataPtr[offset]), data, len);

		tmpPtr[uploadDataLen-1] = gizProtocolSum( tmpPtr , uploadDataLen);
		//GIZWITS_LOG("tmpPtr[%d] = %x \n", uploadDataLen, tmpPtr[uploadDataLen-1]);
		
		ret = uartWrite(tmpPtr, uploadDataLen);
    if(ret < 0)
    {
        GIZWITS_LOG("ERR: uart write error %d \n", ret);
    }

    gizProtocolWaitAck(tmpPtr, uploadDataLen);
		
    if(NULL != uploadDataPtr)
    {
        gizFree(uploadDataPtr);
        uploadDataPtr = NULL;
    }

    return uploadDataLen;
}


int8_t ICACHE_FLASH_ATTR gGatewayLiteSubDevIsOnline(uint16_t subDevNum, subDevOnLine_t *subDevOnLineStatus)
{
		uint8_t *tmpPtr = NULL;
    uint16_t i = 0;
    subDevOnLineHead_t *subDevOnLinePtr = NULL;
    subDevOnLine_t *srcPtr = NULL;
    subDevOnLine_t *dstPtr = NULL;
    uint32_t subDevOnLineLen = 0;
    uint32_t offset = 0;
    int32_t ret = 0;

    if(NULL == subDevOnLineStatus)
    {
        GIZWITS_LOG("[gGatewayLittleSubDevIsOnline]:Input data is NULL \n");
        return -1;
    }

    subDevOnLineLen = sizeof(subDevOnLineHead_t) + subDevNum*sizeof(subDevOnLine_t)+9;
    tmpPtr = (uint8_t *)gizMalloc(subDevOnLineLen);
    if(NULL == tmpPtr)
    {
        GIZWITS_LOG("[gGatewayLittleSubDevIsOnline]:Failed to malloc buffer, size %d \n", subDevOnLineLen);
        return -128;
    }

		subDevOnLineLen -= 4;
		
		tmpPtr[0] = 0xFF;
		tmpPtr[1] = 0xFF;
		tmpPtr[2] = (uint8_t)(subDevOnLineLen>>8);//len
		tmpPtr[3] = (uint8_t)(subDevOnLineLen);
		tmpPtr[4] = CMD_REPORT_P0;//0x1b cmd
		tmpPtr[5] = gizwitsProtocol.sn++;//sn
		tmpPtr[6] = 0x00;//flag
		tmpPtr[7] = 0x00;//flag
				
		subDevOnLineLen += 4;
		
		subDevOnLinePtr = (subDevOnLineHead_t *)(tmpPtr+8);
		
    subDevOnLinePtr->action = ACTION_GATEWAY_SUBDEV_ISONLINE;
    subDevOnLinePtr->count = exchangeBytes(subDevNum);

    offset = sizeof(subDevOnLineHead_t);

    memcpy((uint8_t *)subDevOnLinePtr+offset, (uint8_t *)subDevOnLineStatus, subDevNum*sizeof(subDevOnLine_t));
		
		tmpPtr[subDevOnLineLen-1] = gizProtocolSum( tmpPtr , subDevOnLineLen);
		//GIZWITS_LOG("tmpPtr[%d] = %x \n", subDevOnLineLen, tmpPtr[subDevOnLineLen-1]);
		
		ret = uartWrite(tmpPtr, subDevOnLineLen);
    if(ret < 0)
    {
        GIZWITS_LOG("ERR: uart write error %d \n", ret);
    }

    gizProtocolWaitAck(tmpPtr, subDevOnLineLen);
		
    if(NULL != tmpPtr)
    {
        gizFree(tmpPtr);
				tmpPtr = NULL;
        subDevOnLinePtr = NULL;
    }

    return 0;
}

void ICACHE_FLASH_ATTR gGatewayLiteTest(void)
{
    uint8_t subDevCount = 0;
    uint8_t subDevID[7] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
    uint8_t subDevIDStr[15] = {0};
    uint8_t tmpData[64] = {0x72, 0x0e, 0x30, 0x41, 0x30, 0x30, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x32, 0x05, 0x64, 0x31, 0x37, 0x36, 0x31, 0x35, 0x61, 0x33, 0x61, 0x31, 0x35, 0x39, 0x34, 0x35, 0x31, 0x36, 0x39, 0x39, 0x35, 0x39, 0x65, 0x66, 0x36, 0x62, 0x38, 0x30, 0x35, 0x37, 0x33, 0x63, 0x37, 0x63};
    subDevOnLine_t subDev;

    subDevCount = 1;
    hex2Str((uint8_t *)&subDevIDStr[0], (uint8_t *)&subDevID, 7);
    subDev.len = strlen((uint8_t *)&subDevIDStr[0]);
    gizMemcpy((uint8_t *)subDev.subDevID, (uint8_t *)&subDevIDStr[0], 14);
    subDev.isOnLine = 0x01;
    gGatewayLiteSubDevIsOnline(1, &subDev);

    gGatewayLiteSubDevIssuedProcess((uint8_t *)&tmpData[1], 48);

    gGatewayLiteUpLoadData(TRANSPARENT_TYPE, (uint8_t *)&subDevIDStr[0], subDevID, 7);
}

